
// ---------------------------------------------------------------------------
// CGameBrowserNavigationBar
// ---------------------------------------------------------------------------

#include "stdafx.h"
#include <afxpriv.h>
#include <GdiPlus.h>
#include "GameBrowserNavigationBar.h"
#include "..\..\ChildFrm.h"

using namespace Gdiplus;

const COLORREF g_ChannelBackGround = RGB(195,195,195);              //Window BackGround color
const COLORREF g_EdgeForeGround = RGB(127,127,127);                 //Splitter Bar ForeGround color
const COLORREF g_EdgeBackGround = RGB(227,227,227);                 //Splitter Bar BackGround Color
const COLORREF g_ButtonEdge = RGB(63,63,63);                        //Cascade,Tile,Rectangle Edge
const COLORREF g_FillButtonColor = RGB(238,238,238);                //Fill Cascade,tile Rectangle.
const COLORREF g_LinearGradienBeginColor = RGB(255, 255, 255);      //Mouse Hocked Gradient begin Color
const COLORREF g_LinearGradienEndColor = RGB(204, 231, 238);        //Mouse Hocked Gradient End Color
const COLORREF g_LinearGradienActiveEndColor = RGB(216, 216, 216);  //Active tab Gradient End Color

const UINT g_cNavigateBarHeight = 20;                               //Window height
const UINT g_cTabItemMaxWidth = 150;                                //Max Tab Widht
const UINT g_cTabItemMinWidth = 30;                                 //Min tab Width


const UINT g_separationBarOff = 4;                                  //Splitter Bar offset from Top.and Bottom
const UINT g_OffSetForTabText = 4;                                  //Window Caption offst from Tab left and right

const int g_PreviewToolTipWidth = 150;
const int g_PreviewToolTipHeight = 100;
const int g_PreviewToolTipOffSet = 10;


//
//Implement CGameBrowserNavigationBar
//

IMPLEMENT_DYNAMIC(CGameBrowserNavigationBar,CWnd)

CGameBrowserNavigationBar::CGameBrowserNavigationBar()
{
    m_NavigateBarSize.SetSize(200,g_cNavigateBarHeight);
    m_pActiveChildWnd = NULL;

    m_nButtonWidth = 3 * g_cNavigateBarHeight;   

    m_bNeedToForceRecalcLayout = FALSE;
    m_currentMoseHoverTabItem = NULL;
    m_pCurrentCloseButton = NULL;

    m_bVisible = TRUE;

    
}
CGameBrowserNavigationBar::~CGameBrowserNavigationBar()
{
    DeleteButtonItemInfo();
    if (m_pCurrentCloseButton != NULL)
    {
        delete m_pCurrentCloseButton;
    }
}

//
//Remove all opend TabItem
//
void CGameBrowserNavigationBar::DeleteButtonItemInfo()
{
    int nCount = (int)m_arrayButtonItemInfo.GetCount();
    for(int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayButtonItemInfo[index];
        delete pItem;
        pItem = NULL;
    }
    m_arrayButtonItemInfo.RemoveAll();

}


// ---------------------------------------------------------------------------
// Message Map
// ---------------------------------------------------------------------------

BEGIN_MESSAGE_MAP(CGameBrowserNavigationBar,CWnd)
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_MESSAGE(WM_SIZEPARENT,&CGameBrowserNavigationBar::OnSizeParent)
    ON_MESSAGE(WM_IDLEUPDATECMDUI, &CGameBrowserNavigationBar::OnIdleUpdateCmdUI)
    ON_MESSAGE(WM_MENUSELECT,&CGameBrowserNavigationBar::OnMenuSelectedChanged)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

//
//  Create Navigate Bar,Called By MainFrame
//
BOOL CGameBrowserNavigationBar::CreateNavigateBar(CWnd *pParent,UINT nID)
{
    CRect rt(0,0,0,0);
    CString strClass = AfxRegisterWndClass(CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW,
        LoadCursor(0,IDC_ARROW),::GetSysColorBrush(COLOR_BTNFACE));

  
    
    BOOL bRet = CWnd::CreateEx(WS_EX_LEFT,strClass,
        NULL, WS_CHILD |WS_VISIBLE, rt, pParent, nID);

//    bRet = m_toolTip.CreateStandardHostViewPreview(pParent);

    ASSERT(bRet);

 //   m_toolTip.SetSize(g_PreviewToolTipWidth,g_PreviewToolTipHeight);

    return bRet;
}

//
//Set This Window To Bottom in AOrder,Inorder to Assign a correct position
//
void CGameBrowserNavigationBar::MainFramRecalcLayout()
{
    if (!IsWindow(this->m_hWnd))
    {
        return;
    }
    ::SetWindowPos(this->m_hWnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
}

//
//Child Client window Created
//
BOOL CGameBrowserNavigationBar::OnMDIChildCreate(HWND hwnd)
{
    PTabItemInfo ptabinfo = new TabItemInfo();
    ptabinfo->hwnd = hwnd;
    ptabinfo->bActive = FALSE;
    ptabinfo->bMouseHovered = FALSE;
    ptabinfo->rPosition.SetRect(0,0,0,0);
    ptabinfo->nTabWidth = 0;
    ptabinfo->bShowOnTab = FALSE;
    ptabinfo->eItemType = eNIT_FileTab;
    ptabinfo->nTabWidth = g_cTabItemMinWidth;
    

    m_arrayAllOpendFileTabItemInfo.Add(ptabinfo);
    m_hwndToTabItemInfo.SetAt(hwnd,ptabinfo);

	FileActiveChanged(ptabinfo);

    m_pActiveChildWnd = NULL;

    CheckToShowNavigationBar(TRUE);

    InvalidateRect(NULL,TRUE);
    return TRUE;
}

//
//Child Client Window Destory
//
BOOL CGameBrowserNavigationBar::OnMDIChildDestory(HWND hwnd)
{
    //remove opend iteminfo in AllOpendFiletabItem
    int ndelete = GetAllOpendFileIndexByHwnd(hwnd);
    if (ndelete != -1)
    {
        m_arrayAllOpendFileTabItemInfo.RemoveAt(ndelete);
    }
    //remove item in Arranged Array
    ndelete = GetCurrentShowOnNavIndexByHwnd(hwnd);
    if (ndelete != -1)
    {
        m_arrayCurrentArrangedFiles.RemoveAt(ndelete);
    }
    //remove item on showed Tabs
    ndelete = GetCurrentShowOnNavIndexByHwnd(hwnd);
    if (ndelete != -1)
    {
        m_arrayShowOnTabItemFiles.RemoveAt(ndelete);
    }

    CMapHwndToTabInfo::CPair *pValue = m_hwndToTabItemInfo.PLookup(hwnd);
    if (pValue != NULL)
    {
        PTabItemInfo pItem = pValue->value;
        m_hwndToTabItemInfo.RemoveKey(hwnd);
        delete pItem;
        pItem = NULL;
    }

    m_bNeedToForceRecalcLayout = TRUE;

    RecalcLayoutTabitem();

    InvalidateRect(NULL,TRUE);

    CheckToShowNavigationBar(FALSE);
    return TRUE;
}

void CGameBrowserNavigationBar::CheckToShowNavigationBar(BOOL bOpenDoc)
{
    BOOL bShow = FALSE;

    if (bOpenDoc)
    {
        bShow = TRUE;
    }
    else
    {
        int nCount = m_arrayAllOpendFileTabItemInfo.GetCount();
        if (nCount == 0)
        {
            bShow = FALSE;
        }
        else
        {
            bShow = TRUE;
        }
    }

    if (bShow == m_bVisible)
    {
        return;
    }    
    

    if (bShow)
    {
        m_bVisible = TRUE;
        this->ShowWindow(SW_SHOW);
    }
    else
    {
        m_bVisible = FALSE;
        this->ShowWindow(SW_HIDE);
    }
    
}
int CGameBrowserNavigationBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
    {
        return -1;
    }

    //Add Cascage,Tile,File List Button
    PTabItemInfo cascadeInfo = new TabItemInfo;
    cascadeInfo->eItemType = eNIT_CascadeButton;
    cascadeInfo->hwnd = NULL;
    cascadeInfo->bShowOnTab = true;
    cascadeInfo->nTabWidth = g_cNavigateBarHeight;
    cascadeInfo->bMouseHovered = FALSE;
    cascadeInfo->rPosition.SetRect(0,0,g_cNavigateBarHeight,g_cNavigateBarHeight);
    m_arrayButtonItemInfo.Add(cascadeInfo);

    PTabItemInfo tileInfo = new TabItemInfo;
    tileInfo->eItemType = eNIT_TileButton;
    tileInfo->hwnd = NULL;
    tileInfo->bShowOnTab = true;
    tileInfo->nTabWidth = g_cNavigateBarHeight;
    tileInfo->bMouseHovered = FALSE;
    tileInfo->rPosition.SetRect(g_cNavigateBarHeight,0,2 * g_cNavigateBarHeight,g_cNavigateBarHeight);
    m_arrayButtonItemInfo.Add(tileInfo);

    PTabItemInfo fileListInfo = new TabItemInfo;
    fileListInfo->eItemType = eNIT_ListFilesButton;
    fileListInfo->hwnd = NULL;
    fileListInfo->bShowOnTab = true;
    fileListInfo->nTabWidth = g_cNavigateBarHeight;
    fileListInfo->bMouseHovered = FALSE;
    fileListInfo->rPosition.SetRect(2 * g_cNavigateBarHeight,0,3 * g_cNavigateBarHeight,g_cNavigateBarHeight);
    m_arrayButtonItemInfo.Add(fileListInfo);


    //close Button info
    m_pCurrentCloseButton = new TabItemInfo;
    m_pCurrentCloseButton->eItemType = eNIT_CloseButton;
    m_pCurrentCloseButton->hwnd = NULL;
    m_pCurrentCloseButton->bShowOnTab = true;
    m_pCurrentCloseButton->nTabWidth = 0;
    m_pCurrentCloseButton->bMouseHovered = FALSE;
    m_pCurrentCloseButton->rPosition.SetRect(0,0,0,0);
    return TRUE;
}

//
//On Size Window
//
void CGameBrowserNavigationBar::OnSize(UINT nType, int cx, int cy)
{
    int nShowOnTabCount = m_arrayShowOnTabItemFiles.GetCount();
    int nAllOpenFilesCount = m_arrayCurrentArrangedFiles.GetCount();

    if (nShowOnTabCount < nAllOpenFilesCount)
    {
        RecalcLayoutTabitem();
    }
}

//
//Return Opend index
//
int CGameBrowserNavigationBar::GetAllOpendFileIndexByHwnd(HWND hwnd)
{
    int nRet = -1;
    int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayAllOpendFileTabItemInfo.ElementAt(index);
        if (pItem->hwnd == hwnd)
        {
            return index;
        }
    }

    return nRet;
}

int CGameBrowserNavigationBar::GetCurrentShowOnNavIndexByHwnd(HWND hwnd)
{
    int nRet = -1;
    int nCount = (int)m_arrayCurrentArrangedFiles.GetCount();
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayCurrentArrangedFiles.ElementAt(index);
        if (pItem->hwnd == hwnd)
        {
            return index;
        }
    }

    return -1;
}

int CGameBrowserNavigationBar::GetShowOnTabIndexByHwnd(HWND hwnd)
{
    int nRet = -1;
    int nCount = (int)m_arrayShowOnTabItemFiles.GetCount();
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayShowOnTabItemFiles.ElementAt(index);
        if (pItem->hwnd == hwnd)
        {
            return index;
        }
    }

    return -1;
}

//
//This Function is a very important function,it is called by Mainfram
//To assign a position for NavigationBar
//
LRESULT CGameBrowserNavigationBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
{
    if (m_bVisible == FALSE)
    {
        return FALSE;
    }
    AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;

    int n_oriWidth = lpLayout->rect.right - lpLayout->rect.left;
    int n_oriHeight = lpLayout->rect.bottom - lpLayout->rect.top;

    m_NavigateBarSize.cx = n_oriWidth;

    CRect rcClientPos;
    rcClientPos.top = lpLayout->rect.bottom - m_NavigateBarSize.cy;
    rcClientPos.left = lpLayout->rect.left;
    rcClientPos.right = lpLayout->rect.right;
    rcClientPos.bottom = lpLayout->rect.bottom;

    lpLayout->rect.bottom -= m_NavigateBarSize.cy;


    MoveWindow(rcClientPos.left,rcClientPos.top,rcClientPos.Width(),rcClientPos.Height(),TRUE);  

    return TRUE;

}

//
//Idle Message to calculate tab width
//
LRESULT CGameBrowserNavigationBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam)
{
    CMDIFrameWnd *pMainFrame = (CMDIFrameWnd *)AfxGetMainWnd();
    ASSERT(pMainFrame != NULL);
    if (pMainFrame == NULL)
    {
        return FALSE;
    }
    IdleCheckMousePositino();
    CMDIChildWnd*pActiveWnd = pMainFrame->MDIGetActive();
    if (pActiveWnd == NULL)
    {
        return FALSE;
    }
    int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();
    bool bUpdateUI = FALSE;

    if(pActiveWnd != m_pActiveChildWnd)
    {
        bUpdateUI = TRUE;
    }

    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayAllOpendFileTabItemInfo.ElementAt(index);

        CWnd *pchild = FromHandle(pItem->hwnd);
        ASSERT(pchild != NULL);
        if (pchild->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
        {
            CString strCaption;
			CChildFrame* pActualChild = (CChildFrame*)pchild;
			//if (pActualChild != NULL)
			//	strCaption = pActualChild->GetInterop()->GetDisplayName();
			//else
				pchild->GetWindowText(strCaption);

            if(strCaption.GetLength() <= 0)
            {
				// Should not go here since document name is set by framework
				// BUt we should have a name in case framework did not set
                strCaption = TEXT("Default");
            }

            if (strCaption != pItem->strFullCaption)
            {
                pItem->strFullCaption = strCaption;
                bUpdateUI = TRUE;
                CaculateWidthForTabItem(pItem);

                //If this tab showed on window current,we need to Recalculate all the tab's position
                if (pItem->bShowOnTab)
                {
                    RecalcLayoutTabitem();
                }                
            }
            if ( pchild == pActiveWnd )
            {               
                pItem->bActive = TRUE; 
                if( m_pActiveChildWnd != pActiveWnd)
                {
                    m_pActiveChildWnd = pActiveWnd;
                    CaculateWidthForTabItem(pItem);
                    RecalcLayoutTabitem();
//                    FileActiveChanged(pItem);
                } 
            }
            else
            {
                if (pItem->bActive == TRUE)
                {
                    pItem->bActive = FALSE;
                    CaculateWidthForTabItem(pItem);
                    RecalcLayoutTabitem();
                }
                else
                {
                    pItem->bActive = FALSE;
                }
                
            }
        }
        else
        {
            ASSERT(FALSE);
        }     

    }
 
    if (bUpdateUI)
    {
        InvalidateRect(NULL,TRUE);
    }
    
    return TRUE;
}

//
//Check then Mouse is not in the window client
//
void CGameBrowserNavigationBar::IdleCheckMousePositino()
{
    if (m_currentMoseHoverTabItem != NULL)
    {
        CPoint pt;
        ::GetCursorPos(&pt);
        CRect rcWindow;
        GetWindowRect(&rcWindow);
        if (rcWindow.PtInRect(pt))
        {
            return;
        }
        else
        {
            m_currentMoseHoverTabItem->bMouseHovered = FALSE;
            m_currentMoseHoverTabItem = NULL;
            InvalidateRect(NULL,TRUE);
            ShowToolTip(false);
        }
    }
}
CGameBrowserNavigationBar::PTabItemInfo CGameBrowserNavigationBar::GetActiveOpendFileItemInfo()
{
    PTabItemInfo pItemActive;
    int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayAllOpendFileTabItemInfo.ElementAt(index);
        if (pItem->bActive == TRUE)
        {
            pItemActive = pItem;
            break;
        }
    }
    return pItemActive;
}



void CGameBrowserNavigationBar::CaculateWidthForTabItem(PTabItemInfo pItemInfo)
{
    CString strCaption = pItemInfo->strFullCaption;//TEXT("kdieTGLdkiek kitnkeiTGGGGGGGGkdkdkdksl.ipt");
    CDC* dcWindow = GetWindowDC();
    Graphics gdc(*dcWindow);
    Gdiplus::Font  * font = NULL;//(L"Arial",8);
    if (pItemInfo->bActive)
    {
        font = new Gdiplus::Font(L"Arial",8,FontStyleBold);
    }
    else
    {
        font = new Gdiplus::Font(L"Arial",8);
    }
    
    int nGEdgeOffSet = 2;
    if (pItemInfo->bActive)
    {
        nGEdgeOffSet = 6 * g_OffSetForTabText;
    }
    //Calculate the width for Caption
    //

    SizeF layoutSize(REAL(g_cTabItemMaxWidth - nGEdgeOffSet),(REAL)g_cNavigateBarHeight);
    StringFormat format;
    format.SetAlignment(StringAlignmentNear);
    format.SetFormatFlags(StringFormatFlagsLineLimit);
    SizeF stringSize;
    INT codepointsFitted = 0;
    INT linesFilled = 0;
    int nCaptionLength = strCaption.GetLength();
    gdc.MeasureString(strCaption,strCaption.GetLength(),font,layoutSize,&format,&stringSize,&codepointsFitted,&linesFilled);

    delete font;
    //If all the word can show on tab
    if (codepointsFitted >= strCaption.GetLength())
    {
        pItemInfo->strShowCaption = strCaption;
        int nSize = (int)stringSize.Width + nGEdgeOffSet;
        if(nSize < g_cTabItemMinWidth)
        {
            nSize = g_cTabItemMinWidth;
        }

        pItemInfo->nTabWidth = nSize;
        return;
    }
    //The Caption can't show complete.So we need to add ...
    int nBigNum = strCaption.GetLength() - codepointsFitted;

    int nIndex = strCaption.ReverseFind('.');
    CString strSuffix;
    CString strNameNotSuffix;
    if (nIndex != -1)
    {
        strSuffix = strCaption.Right(strCaption.GetLength() - nIndex - 1);
        strNameNotSuffix = strCaption.Left(nIndex);
    }
    else
    {
        strNameNotSuffix = strCaption;
    }
    int nStrLengthLeave = codepointsFitted - strSuffix.GetLength();
    
    strNameNotSuffix = strCaption.Left(nStrLengthLeave - 2);
    strNameNotSuffix += L"...";

    CString strShowName = strNameNotSuffix + strSuffix;

    //Save info
    pItemInfo->strShowCaption = strShowName;
    pItemInfo->nTabWidth = g_cTabItemMaxWidth;
}

//
//Active tab Changed
//
void CGameBrowserNavigationBar:: FileActiveChanged(PTabItemInfo pItemInfo)
{
    int nExit = GetCurrentShowOnNavIndexByHwnd(pItemInfo->hwnd);
    if (nExit == -1)
    {
        m_arrayCurrentArrangedFiles.InsertAt(0,pItemInfo);
        RecalcLayoutTabitem();
        return;
    }
    CRect rcClient;
    GetClientRect(rcClient);
    CRect itemPosition = pItemInfo->rPosition;
    if (itemPosition.right < rcClient.Width() && pItemInfo->bShowOnTab)
    {
        if (m_bNeedToForceRecalcLayout == TRUE)
        {
            m_bNeedToForceRecalcLayout = FALSE;
             RecalcLayoutTabitem();
        }
        return;
    }
    m_arrayCurrentArrangedFiles.RemoveAt(nExit);
    m_arrayCurrentArrangedFiles.InsertAt(0,pItemInfo);
    RecalcLayoutTabitem();
}

//
//Recalculate all the Tabs Position
//
void CGameBrowserNavigationBar::RecalcLayoutTabitem()
{
   int nCount = (int)m_arrayCurrentArrangedFiles.GetCount();

   m_arrayShowOnTabItemFiles.RemoveAll();

   CRect rcClient;
   GetClientRect(rcClient);
   int nBegin = m_nButtonWidth;
   for (int index = 0;index < nCount;index++)
   {
       PTabItemInfo pItem = m_arrayCurrentArrangedFiles[index];
       int nRight = nBegin + pItem->nTabWidth;
       if (nRight >= rcClient.right)
       {
            pItem->bShowOnTab = FALSE;
            nBegin = nRight;
            continue;
       }
       pItem->bShowOnTab = TRUE;
       pItem->rPosition.SetRect(nBegin,0,nRight,rcClient.Height());
       nBegin = nRight;
       m_arrayShowOnTabItemFiles.Add(pItem);
   }
}

BOOL CGameBrowserNavigationBar::OnEraseBkgnd(CDC* pDC)
{
    return TRUE;
}

void CGameBrowserNavigationBar::OnPaint()
{
    CPaintDC dc(this); 
    CDC hdcMem;
    hdcMem.CreateCompatibleDC(&dc);
   
    CRect rt;
    GetClientRect(rt);

    HBITMAP hbmScreen = CreateCompatibleBitmap(dc,rt.Width(),rt.Height());
    HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem,hbmScreen);

    //Draw all the info on the memery DC
    PaintOnMemoryDC(hdcMem);

    BOOL bRet = BitBlt(dc,0,0,rt.Width(),rt.Height(),hdcMem,0,0,SRCCOPY);

    SelectObject(hdcMem,hOldBmp);
    DeleteObject(hbmScreen);
    
}

void CGameBrowserNavigationBar::PaintOnMemoryDC(CDC &dcmemery)
{
    CRect rtClient;
    GetClientRect(rtClient);
    dcmemery.FillSolidRect(rtClient, g_ChannelBackGround);

    //Drate Edge
    CPen cEdgePen(PS_SOLID,1,g_EdgeForeGround);
    HPEN hOldPen = (HPEN)dcmemery.SelectObject(cEdgePen);
    dcmemery.SelectObject(hOldPen);
    dcmemery.MoveTo(0,0);
    dcmemery.LineTo(rtClient.Width() - 1,0);
    dcmemery.LineTo(rtClient.Width() - 1,rtClient.Height() - 1);
    dcmemery.LineTo(0,rtClient.Height() - 1);
    dcmemery.LineTo(0,0);
    dcmemery.SelectObject(hOldPen);


    //Draw Tools Button
    DrawToolButtons(dcmemery);

    //Draw File Tabs
    DrawFilesTab(dcmemery);
}

//
//Draw Cascade,Tile,FileList Button
//
void CGameBrowserNavigationBar::DrawToolButtons(CDC &dc)
{
    int nCount = (int)m_arrayButtonItemInfo.GetCount();
    for(int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayButtonItemInfo[index];

        if (pItem->bMouseHovered == TRUE)
        {  
            Color clBegin;
            clBegin.SetFromCOLORREF(g_LinearGradienBeginColor);
            Color clEnd;
            clEnd.SetFromCOLORREF(g_LinearGradienEndColor);
            Graphics gDC(dc);
            LinearGradientBrush linGrBrush(
                Point(0, 0),
                Point(0, g_cNavigateBarHeight),
                clBegin,  
                clEnd);    

            //Draw Back Ground;
            CRect rcPosition = pItem->rPosition;
            rcPosition.DeflateRect(1,1,1,1);
            gDC.FillRectangle(&linGrBrush,rcPosition.left,rcPosition.top,rcPosition.Width(),rcPosition.Height());

        }

        switch (pItem->eItemType)
        {
        case eNIT_CascadeButton:
            {


                CRect rcPosition = pItem->rPosition;
                rcPosition.DeflateRect(3,3,3,3);

                int xMidWidth = rcPosition.Width()/2;
                int yMidWidth = rcPosition.Height()/2;

                int xOff = yMidWidth - 2;
                Point p3List[3];

                p3List[0].X = xOff;//rcPosition.left + xMidWidth;
                p3List[0].Y = rcPosition.top + yMidWidth;

                p3List[1].X = rcPosition.right - xOff;
                p3List[1].Y = p3List[0].Y - yMidWidth;

                p3List[2].X = rcPosition.right - xOff;
                p3List[2].Y = p3List[0].Y + yMidWidth;

                Graphics gDC(dc);
                gDC.SetSmoothingMode(SmoothingModeHighQuality);
                Color cl;
                cl.SetFromCOLORREF(g_ButtonEdge);
                SolidBrush slidb(cl);

                gDC.FillPolygon(&slidb,p3List,3);  
                
            }
            break;
        case eNIT_TileButton:
            {
                CRect rcPosition = pItem->rPosition;
                rcPosition.DeflateRect(3,3,3,3);

                int xMidWidth = rcPosition.Width()/2;
                int yMidWidth = rcPosition.Height()/2;

                int xOff = yMidWidth - 2;
                Point p3List[3];

                p3List[0].X = rcPosition.right - xOff + 2;//rcPosition.left + xMidWidth;
                p3List[0].Y = rcPosition.top + yMidWidth;

                p3List[1].X = rcPosition.left + xOff;
                p3List[1].Y = p3List[0].Y - yMidWidth;

                p3List[2].X = rcPosition.left + xOff;
                p3List[2].Y = p3List[0].Y + yMidWidth;

                Graphics gDC(dc);
                gDC.SetSmoothingMode(SmoothingModeHighQuality);
                Color cl;
                cl.SetFromCOLORREF(g_ButtonEdge);
                SolidBrush slidb(cl);

                gDC.FillPolygon(&slidb,p3List,3);  
                
            }
            break;
        case eNIT_ListFilesButton:
            {
                CRect rcPosition = pItem->rPosition;
                rcPosition.DeflateRect(3,3,3,3);

                int xMidWidth = rcPosition.Width()/2;
                int yMidWidth = rcPosition.Height()/2;

                int xOff = yMidWidth - 2;
                Point p3List[3];

                p3List[0].X = rcPosition.left + xMidWidth;
                p3List[0].Y = rcPosition.bottom - xOff;

                p3List[1].X = p3List[0].X - xOff;
                p3List[1].Y = p3List[0].Y - yMidWidth;

                p3List[2].X = p3List[0].X + xOff;
                p3List[2].Y = p3List[0].Y - yMidWidth;

                Graphics gDC(dc);
                gDC.SetSmoothingMode(SmoothingModeHighQuality);
                Color cl;
                cl.SetFromCOLORREF(g_ButtonEdge);
                SolidBrush slidb(cl);

                gDC.FillPolygon(&slidb,p3List,3);  

            }
        	break;
        }

        //Draw Edge;
        CRect rcEdge = pItem->rPosition;
        Graphics gdcEdge(dc);
        Color cl;
        cl.SetFromCOLORREF(g_ButtonEdge);
        Pen pCloseLine(cl,1.0f);
        Point p1(rcEdge.left,rcEdge.top);
        Point p2(rcEdge.left,rcEdge.bottom);
        //gdcEdge.DrawLine(&pCloseLine,p1,p2);
        p1.X = rcEdge.right;
        p2.X = rcEdge.right;
        gdcEdge.DrawLine(&pCloseLine,p1,p2);

    }

}

void CGameBrowserNavigationBar::DrawRectangle(CRect &rc,CDC &dc)
{
    Graphics gDC(dc);
   // gDC.SetSmoothingMode(SmoothingModeHighQuality); 
    Color cl;
    cl.SetFromCOLORREF(g_ButtonEdge);
    Pen pSingleLine(cl,1.0f);

    Color clBack;
    clBack.SetFromCOLORREF(g_FillButtonColor);
    SolidBrush solidBrush(clBack);
    gDC.FillRectangle(&solidBrush,rc.left,rc.top,rc.Width(),rc.Height());

    gDC.DrawRectangle(&pSingleLine,rc.left,rc.top,rc.Width(),rc.Height());

    Pen pDoubleLine(cl,2.0f);
    gDC.DrawLine(&pDoubleLine,rc.left +1,rc.top,rc.right,rc.top);
}

void CGameBrowserNavigationBar::DrawFilesTab(CDC &dc)
{

    int nCount = (int)m_arrayShowOnTabItemFiles.GetCount();

    CRect rcClient;
    GetClientRect(rcClient);
    int nBegin = m_nButtonWidth;
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayShowOnTabItemFiles[index]; 

        if (pItem->bShowOnTab == FALSE)
        {
            continue;
        }

        if (TRUE == pItem->bActive)
        { 
            DrawActiveFileTab(dc,pItem);           
        }
        else
        {
            DrawDeActiveFileTab(dc,pItem);
        }

        //Draw Splitter Line on Left
        CPen cEdgePenLeft(PS_SOLID,1,g_EdgeBackGround);
        HPEN hOldPenLeft = (HPEN)dc.SelectObject(cEdgePenLeft);
        dc.MoveTo(pItem->rPosition.left + 1,g_separationBarOff);
        dc.LineTo(pItem->rPosition.left + 1,pItem->rPosition.Height() - g_separationBarOff);
        dc.SelectObject(hOldPenLeft);

        //Draw Splitter Line on right
        CPen cEdgePenRight(PS_SOLID,1,g_EdgeForeGround);
        HPEN hOldPenRight = (HPEN)dc.SelectObject(cEdgePenRight);
        dc.MoveTo(pItem->rPosition.right,g_separationBarOff);
        dc.LineTo(pItem->rPosition.right,pItem->rPosition.Height() - g_separationBarOff);
        dc.SelectObject(hOldPenRight);


    }
}

void CGameBrowserNavigationBar::DrawActiveFileTab(CDC &dc,PTabItemInfo pItem)
{
    Graphics gDC(dc);  

   //Draw Back Ground;
    CRect rcPosition = pItem->rPosition;
    rcPosition.DeflateRect(1,1,1,1);
    if (pItem->bMouseHovered == FALSE)
    {  
        Color clBegin;
        clBegin.SetFromCOLORREF(g_LinearGradienBeginColor);
        Color clEnd;
        clEnd.SetFromCOLORREF(g_LinearGradienActiveEndColor);
        LinearGradientBrush linGrBrush(
            Point(0, 0),
            Point(0, g_cNavigateBarHeight),
            clBegin,  
            clEnd);
        gDC.FillRectangle(&linGrBrush,rcPosition.left + 1,rcPosition.top,rcPosition.Width(),rcPosition.Height());
    }
    else
    {
        Color clBegin;
        clBegin.SetFromCOLORREF(g_LinearGradienBeginColor);
        Color clEnd;
        clEnd.SetFromCOLORREF(g_LinearGradienEndColor);

        LinearGradientBrush linGrBrush(
            Point(0, 0),
            Point(0, g_cNavigateBarHeight),
            clBegin,  
            clEnd);
        gDC.FillRectangle(&linGrBrush,rcPosition.left + 1,rcPosition.top,rcPosition.Width(),rcPosition.Height());       

    }

    //Draw Title
    Gdiplus::Font  font(L"Arial",8,FontStyleBold);
    CString strCaption = pItem->strShowCaption;
    PointF origin((REAL)(rcPosition.left + 2),(REAL)(rcPosition.top + 2));
    SolidBrush blackBrush(Color(255,0,0,0));
    gDC.DrawString(strCaption,strCaption.GetLength(),&font,origin,&blackBrush);


    //Draw Close Button;
    gDC.SetSmoothingMode(SmoothingModeHighQuality); 
    int nSuffWidht = g_cNavigateBarHeight/5;

     CRect nRectCloseButton;
    nRectCloseButton.SetRect(rcPosition.right - 4 * nSuffWidht,nSuffWidht,
                               rcPosition.right - nSuffWidht, 4 * nSuffWidht);

    //Set Close Button position Info;
    m_pCurrentCloseButton->rPosition = nRectCloseButton;
    m_pCurrentCloseButton->nTabWidth = nRectCloseButton.Width();

    SolidBrush solidBrushCircle(Color(255,155,155,155));

    gDC.FillEllipse(&solidBrushCircle,nRectCloseButton.left,nRectCloseButton.top,
                nRectCloseButton.Width(),nRectCloseButton.Height());


    
    Pen pCloseLine(Color(255,250,250,250),2.0f);
    Point p1(nRectCloseButton.left + nSuffWidht,nRectCloseButton.top + nSuffWidht);
    Point p2(nRectCloseButton.right - nSuffWidht,nRectCloseButton.bottom - nSuffWidht);
    gDC.DrawLine(&pCloseLine,p1,p2);

    Point p3(nRectCloseButton.left + nSuffWidht,nRectCloseButton.bottom - nSuffWidht);
    Point p4(nRectCloseButton.right - nSuffWidht,nRectCloseButton.top + nSuffWidht);

    gDC.DrawLine(&pCloseLine,p3,p4);

    if (m_pCurrentCloseButton->bMouseHovered == FALSE)
    {
        gDC.DrawEllipse(&pCloseLine,nRectCloseButton.left,nRectCloseButton.top,
            nRectCloseButton.Width(),nRectCloseButton.Height());
    }

}

void CGameBrowserNavigationBar::DrawDeActiveFileTab(CDC &dc,PTabItemInfo pItem)
{
     Graphics gDC(dc);   

     if (pItem->bMouseHovered == TRUE)
     {  
         LinearGradientBrush linGrBrush(
             Point(0, 0),
             Point(0, g_cNavigateBarHeight),
             Color(255, 255, 255, 255),  
             Color(255, 204, 231, 238));    

         //Draw Back Ground;
         CRect rcPosition = pItem->rPosition;
         rcPosition.DeflateRect(1,1,1,1);

         gDC.FillRectangle(&linGrBrush,rcPosition.left,rcPosition.top,rcPosition.Width(),rcPosition.Height());

     }

    //Draw Title
    Gdiplus::Font  font(L"Arial",8);
    CString strCaption = pItem->strShowCaption;
    CRect rcPosition = pItem->rPosition;
    rcPosition.DeflateRect(1,1,1,1);

    PointF origin((REAL)(rcPosition.left + 1),(REAL)(rcPosition.top + 2));
    SolidBrush blackBrush(Color(255,0,0,0));
    gDC.DrawString(strCaption,strCaption.GetLength(),&font,origin,&blackBrush);
}

//
//Mouse Move
//
void CGameBrowserNavigationBar::OnMouseMove( UINT ntype, CPoint pt)
{
    bool bHoveredChanged = false;

    //Check Close Button
    if (m_pCurrentCloseButton != NULL)
    {
        CRect rcClose = m_pCurrentCloseButton->rPosition;
        if (rcClose.PtInRect(pt))
        {
            if (m_pCurrentCloseButton->bMouseHovered == FALSE)
            {
                m_pCurrentCloseButton->bMouseHovered = TRUE;
                InvalidateRect(NULL,FALSE);
            }
        }
        else
        {
            if (m_pCurrentCloseButton->bMouseHovered == TRUE)
            {
                m_pCurrentCloseButton->bMouseHovered = FALSE;
                InvalidateRect(NULL,FALSE);
            }
        }
    }
    //Check hover changed
    if (m_currentMoseHoverTabItem != NULL)
    {
        CRect rcPosition = m_currentMoseHoverTabItem->rPosition;
        if(rcPosition.PtInRect(pt))
        {
            m_currentMoseHoverTabItem->bMouseHovered = true;
            return;
        }
        else
        {
            m_currentMoseHoverTabItem->bMouseHovered = false;
            bHoveredChanged = true;
        }
    }

    m_currentMoseHoverTabItem = NULL;

    //Check position on files tab
    int nCount = (int)m_arrayShowOnTabItemFiles.GetCount();  
    for (int index = 0;index < nCount;index++)
    {
        PTabItemInfo pItem = m_arrayShowOnTabItemFiles[index]; 

        CRect rcPosition = pItem->rPosition;
        if(rcPosition.PtInRect(pt))
        {
            pItem->bMouseHovered = true;
            m_currentMoseHoverTabItem = pItem;       
            bHoveredChanged = true;
        }
        else
        {
            pItem->bMouseHovered = false;
        }
    }

    //Check position on Buttons
    int nCountButton = (int)m_arrayButtonItemInfo.GetCount();
    for(int index = 0;index < nCountButton;index++)
    {
        PTabItemInfo pItem = m_arrayButtonItemInfo[index]; 
        CRect rcPosition = pItem->rPosition;
        if(rcPosition.PtInRect(pt))
        {
            pItem->bMouseHovered = true;
            m_currentMoseHoverTabItem = pItem;       
            bHoveredChanged = true;
        }
        else
        {
            pItem->bMouseHovered = false;
        }
    }


    if (bHoveredChanged == TRUE)
    { 
        InvalidateRect(NULL,TRUE);

        ////Show ToolTip
        //if (m_currentMoseHoverTabItem != NULL && m_currentMoseHoverTabItem->eItemType == eNIT_FileTab)
        //{  
        //    CWnd* pWnd = FromHandle(m_currentMoseHoverTabItem->hwnd);
        //    CStandardHostChildFrame *pChildFrame = (CStandardHostChildFrame*)(pWnd);
        //    HBITMAP hBitmap = NULL;
        //    CString strFilePath;
        //    if(pChildFrame != NULL)
        //    {
        //        hBitmap = pChildFrame->GetInterop()->CreateImage(g_PreviewToolTipWidth,g_PreviewToolTipHeight);
        //        strFilePath = pChildFrame->GetInterop()->GetDocumentFilePath();
        //    }
        //    if (hBitmap != NULL)
        //    { 
        //        m_toolTip.SetToolTipInfo(hBitmap,strFilePath);
        //        CRect rcWindow = m_currentMoseHoverTabItem->rPosition;
        //        ClientToScreen(&rcWindow);
        //        int nMid = rcWindow.Width()/2;
        //        ShowToolTip(true,rcWindow.left + nMid - g_PreviewToolTipWidth/2,rcWindow.top - g_PreviewToolTipHeight- g_PreviewToolTipOffSet);

        //    }
        //}
        //else
        //{
        //    ShowToolTip(false);
        //}

    }

}

//
//On LbuttonUp
//
void CGameBrowserNavigationBar::OnLButtonUp( UINT nFlags,CPoint point)
{
    if (m_currentMoseHoverTabItem == NULL)
    {
        return;
    }

    switch (m_currentMoseHoverTabItem->eItemType)
    {
    case eNIT_CascadeButton:
        {
            OnCascadeWindow();
        }
    	break;
    case eNIT_TileButton:
        {
            OnTileWindow();
        }
        break;
    case eNIT_ListFilesButton:
        {
            OnFileListMenu(m_currentMoseHoverTabItem,point);
        }
        break;
    case eNIT_FileTab:
        {
            OnFileTabClicked(m_currentMoseHoverTabItem);
        }
        break;
    }
}

//
//Cascade Child Window
//
void CGameBrowserNavigationBar::OnCascadeWindow()
{
    //CMDIFrameWnd *pMainFram = (CMDIFrameWnd*)AfxGetMainWnd(); 
    //ASSERT(pMainFram != NULL);
    //if (pMainFram == NULL)
    //{
    //    return;
    //}    
    //pMainFram->MDICascade();
}
//
//Tile Child Window
//
void CGameBrowserNavigationBar::OnTileWindow()
{
    //CMDIFrameWnd *pMainFram = (CMDIFrameWnd*)AfxGetMainWnd();
    //pMainFram->MDITile();
}

//
//Show Content Menu
//
void CGameBrowserNavigationBar::OnFileListMenu(PTabItemInfo pItemInfo,CPoint pt)
{
    if (pItemInfo == NULL || pItemInfo->eItemType != eNIT_ListFilesButton)
    {
        return;
    }
    if (m_arrayAllOpendFileTabItemInfo.GetCount() <= 0)
    {
        return;
    }

    CMenu PopMenu;
    PopMenu.CreatePopupMenu();

    int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();

    for (int index = 0;index< nCount;index++)
    {
        PTabItemInfo pItem = m_arrayAllOpendFileTabItemInfo[index];
        int nId = AFX_IDM_FIRST_MDICHILD + index;
        UINT nFlags = MF_STRING ;
        if (pItem->bActive)
        {
            nFlags |= MF_CHECKED;
        }
        else
        {
            nFlags |= MF_UNCHECKED;
        }

        //If File Count is large than 30,then show it in another Column.
        int xSeparator = index%30;
        if (xSeparator == 0 && index != 0)
        {
            nFlags |= MF_MENUBREAK;
        }

        BOOL bRet = PopMenu.AppendMenu(nFlags,nId,pItem->strShowCaption);
        ASSERT(bRet);
    }

    CRect rcPosition = pItemInfo->rPosition;
    CPoint ptPosition;
    ptPosition.x = rcPosition.left;
    ptPosition.y = rcPosition.bottom;

    ClientToScreen(&ptPosition);    

    BOOL bRet = ::TrackPopupMenu(PopMenu.m_hMenu,TPM_TOPALIGN|TPM_VERTICAL,ptPosition.x,ptPosition.y,0,this->m_hWnd,NULL);
    ASSERT(bRet);
}

BOOL CGameBrowserNavigationBar::OnCommand(WPARAM wParam,LPARAM lParam)
{
    UINT Id = LOWORD(wParam);
    int nIndex = Id - AFX_IDM_FIRST_MDICHILD;
    int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();
    if (nIndex >= nCount)
    {
        return FALSE;
    }

    PTabItemInfo pItem = m_arrayAllOpendFileTabItemInfo[nIndex];
    if (pItem->bActive)
    {
        return FALSE;
    }
    //Active Selected File
    OnFileTabClicked(pItem);
    return TRUE;
}

// On Document menu selected changed
LRESULT CGameBrowserNavigationBar::OnMenuSelectedChanged(WPARAM wParam,LPARAM lParam)
{
    UINT Id = LOWORD(wParam);
    UINT nType = HIWORD(wParam);
    HMENU hwndMenu = (HMENU)(lParam);

    if (nType & MF_MOUSESELECT)
    {
        int nIndex = Id - AFX_IDM_FIRST_MDICHILD;
        //if (nIndex < 0)
        //{
        //    ShowToolTip(false);
        //    return -1;
        //}
        int nCount = (int)m_arrayAllOpendFileTabItemInfo.GetCount();
        if (nIndex >= nCount)
        {
            return -1;
        }

        ////Show ToolTip
        //PTabItemInfo pItemInfo = m_arrayAllOpendFileTabItemInfo[nIndex];
        //CWnd* pWnd = FromHandle(pItemInfo->hwnd);
        //CStandardHostChildFrame *pChildFrame = (CStandardHostChildFrame*)(pWnd);
        //HBITMAP hBitmap = NULL;
        //CString strFilePath;
        //if(pChildFrame != NULL)
        //{
        //    hBitmap = pChildFrame->GetInterop()->CreateImage(g_PreviewToolTipWidth,g_PreviewToolTipHeight);
        //    strFilePath = pChildFrame->GetInterop()->GetDocumentFilePath();
        //}
        //if (hBitmap != NULL)
        //{ 
        //    m_toolTip.SetToolTipInfo(hBitmap,strFilePath);
        //    RECT rcMenuPosition ;
        //    BOOL bItem =::GetMenuItemRect(NULL,hwndMenu,nIndex,&rcMenuPosition);  
        //    ShowToolTip(true,rcMenuPosition.right + g_PreviewToolTipOffSet,rcMenuPosition.bottom - g_PreviewToolTipHeight);

        //}
    }
    return -1;
}
//Active Item
void CGameBrowserNavigationBar::OnFileTabClicked(PTabItemInfo pItemInfo)
{
    CMDIFrameWnd *pMainFram = (CMDIFrameWnd*)AfxGetMainWnd();
    HWND hMdiClient = pMainFram->m_hWndMDIClient;
    if (pItemInfo->bActive)
    {
        if (m_pCurrentCloseButton->bMouseHovered)
        {
            //Important to set this param
            m_currentMoseHoverTabItem = NULL; 
            ShowToolTip(FALSE);
            ::SendMessage(pItemInfo->hwnd,WM_CLOSE,0,0); 
        }
        return;
    }	
    pMainFram->LockWindowUpdate();
    CWnd* pWnd = FromHandle(pItemInfo->hwnd);
    pMainFram->MDIActivate(pWnd);  
    pMainFram->UnlockWindowUpdate();
}

void CGameBrowserNavigationBar::ShowToolTip(BOOL bVisible,int xPos,int yPos)
{  
    //m_toolTip.HidePreview();
    //if (bVisible == FALSE)
    //{      
    //    return;
    //}  
    //m_toolTip.ShowPreview(xPos,yPos);
}
